﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Linq.Mapping;
using Microsoft.Data.Sqlite;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using KorbeRTR.Utility;

namespace KorbeRTR.Models
{
    /// <summary>
    /// 镀铜槽电流
    /// </summary>
    public class CuSlotCurrent
    {
        public double[] A;
        public double[] B;

        public CuSlotCurrent()
        {
            A = new double[3] { 0, 0, 0 };
            B = new double[3] { 0, 0, 0 };
        }

        public static implicit operator CuSlotCurrent(SlotCurrentRecord record)
        {
            var tmp = new CuSlotCurrent();
            tmp.A[0] = record.A1;
            tmp.B[0] = record.B1;
            tmp.A[1] = record.A2;
            tmp.B[1] = record.B2;
            //tmp.A[2] = record.A3;
            //tmp.B[2] = record.B3;
            return tmp;
        }
    }

    /// <summary>
    /// 镀铜槽电流记录
    /// </summary>
    public class SlotCurrentRecord
    {
        [Column]
        public Int64 Id { get; set; }

        [Column]
        public Int64 Parent { get; set; }

        [Column]
        public Int64 Slot { get; set; }

        [Column]
        public double A1 { get; set; }

        [Column]
        public double B1 { get; set; }

        [Column]
        public double A2 { get; set; }

        [Column]
        public double B2 { get; set; }

        //[Column]
        //public double A3 { get; set; }

        //[Column]
        //public double B3 { get; set; }

        /// <summary>
        /// 软删除标志
        /// </summary>
        [Column]
        public bool IsDeleted { get; set; }
    }

    /// <summary>
    /// 镀铜槽电流记录视图
    /// </summary>
    public class CurrentRecordView
    {
        [Column]
        public Int64 Id { get; set; }

        /// <summary>
        /// 时间
        /// </summary>
        [Column]
        public DateTime Time { get; set; }

        /// <summary>
        /// 软删除标志
        /// </summary>
        [Column]
        public bool IsDeleted { get; set; }

        public CuSlotCurrent[] SlotCurrent;

        public CurrentRecordView()
        {
            SlotCurrent = new CuSlotCurrent[KorbeRTR.Config.镀铜槽数];
            for(int i=0; i<SlotCurrent.Length; i++)
            {
                SlotCurrent[i] = new CuSlotCurrent();
            }
        }

        /// <summary>
        /// 删除n个月前的数据
        /// </summary>
        public static bool DeleteBeforeMonth(DateTime time, int n)
        {
            time = time.AddMonths(-n);
            time = new DateTime(time.Year, time.Month, 1, 0, 0, 0);

            int rows = OperationRecordDBHelper.ExecuteNonQuery("DELETE FROM SlotCurrentRecords WHERE Parent IN (SELECT Id FROM LineCurrentRecords WHERE Time < @Time)",
                new SqliteParameter("@Time", time.ToSqlTime())
                );

            rows = OperationRecordDBHelper.ExecuteNonQuery("DELETE FROM LineCurrentRecords WHERE Time < @Time",
                new SqliteParameter("@Time", time.ToSqlTime())
                );

            return rows > 0;
        }

        /// <summary>
        /// 添加电流记录
        /// </summary>
        /// <returns></returns>
        public static bool Add(CurrentRecordView view)
        {
            var dt = CurrentRecordDBHelper.ExecuteTable(
                @"INSERT INTO LineCurrentRecords(Time) VALUES(@Time);
                    SELECT LAST_INSERT_ROWID();",
                new SqliteParameter("@Time", view.Time.ToSqlTime()));

            Int64 parent = (Int64)dt.Rows[0][0];

            using (var conn = CurrentRecordDBHelper.Open())
            {
                using (var trans = conn.BeginTransaction())
                {
                    try
                    {
                        for (int i=0; i<view.SlotCurrent.Length; i++)
                        {
                            var slot = view.SlotCurrent[i];

                            CurrentRecordDBHelper.ExecuteNonQuery(trans,
                                @"INSERT INTO SlotCurrentRecords(Parent,Slot,A1,B1,A2,B2)
                                    VALUES(@Parent,@Slot,@A1,@B1,@A2,@B2)",
                                new SqliteParameter("@Parent", parent),
                                new SqliteParameter("@Slot", i+1),
                                new SqliteParameter("@A1", slot.A[0]),
                                new SqliteParameter("@B1", slot.B[0]),
                                new SqliteParameter("@A2", slot.A[1]),
                                new SqliteParameter("@B2", slot.B[1])
                                //new SqliteParameter("@A3", slot.A[2]),
                                //new SqliteParameter("@B3", slot.B[2])
                                );
                        }

                        trans.Commit();
                    }
                    catch (Exception err)
                    {
                        trans.Rollback();
                        throw err;
                    }
                }
            }

            return true;
        }

        /// <summary>
        /// 列出电流记录
        /// </summary>
        /// <returns></returns>
        public static List<CurrentRecordView> ListAll()
        {
            var dict = new Dictionary<Int64, CurrentRecordView>();
            {   // 读取产线电流记录
                var dt = CurrentRecordDBHelper.ExecuteTable("SELECT * FROM LineCurrentRecords WHERE IsDeleted=FALSE");
                foreach (var dm in dt.ToModel<CurrentRecordView>())
                {
                    dict[dm.Id] = dm;
                }
            }

            {   // 读取槽电流记录
                var dt = CurrentRecordDBHelper.ExecuteTable("SELECT * FROM SlotCurrentRecords");
                var list = dt.ToModel<SlotCurrentRecord>();

                // 产线记录和槽记录匹配
                foreach (var slot in list)
                {
                    if (dict.ContainsKey(slot.Parent))
                    {
                        if (0<slot.Slot && slot.Slot<= dict[slot.Parent].SlotCurrent.Length)
                            dict[slot.Parent].SlotCurrent[slot.Slot-1] = slot;
                    }
                }
            }

            return dict.Values.ToList();
        }

        /// <summary>
        /// 查询 t0 到 t1 时间内的记录
        /// </summary>
        /// <param name="t0">起始时间</param>
        /// <param name="t1">终止时间</param>
        /// <returns></returns>
        public static List<CurrentRecordView> Select(DateTime t0, DateTime t1)
        {
            if (t0 > t1)
            {
                AuxLib.Swap(ref t0, ref t1);
            }

            var dict = new Dictionary<Int64, CurrentRecordView>();
            Int64 MinId = 0;
            Int64 MaxId = 0;
            {   // 读取产线电流记录
                var dt = CurrentRecordDBHelper.ExecuteTable("SELECT * FROM LineCurrentRecords WHERE IsDeleted=FALSE AND (Time BETWEEN @T0 AND @T1)",
                    new SqliteParameter("@T0", t0.ToSqlTime()),
                    new SqliteParameter("@T1", t1.ToSqlTime())
                    );
                if (dt.Rows.Count > 0)
                {
                    MinId = MaxId = Convert.ToInt64(dt.Rows[0]["Id"]);
                }
                foreach(var dm in dt.ToModel<CurrentRecordView>())
                {
                    dict[dm.Id] = dm;

                    if (dm.Id < MinId) MinId = dm.Id;

                    if (dm.Id > MaxId) MaxId = dm.Id;
                }
            }

            {   // 读取槽电流记录
                var list = new List<SlotCurrentRecord>(/*dt.Rows.Count*/);

                using (var conn = new SqliteConnection(CurrentRecordDBHelper.ConnectString))
                {
                    conn.Open();

                    var cmd = new SqliteCommand("SELECT Id,IsDeleted,Parent,Slot,A1,A2,B1,B2 FROM SlotCurrentRecords WHERE Parent BETWEEN @P1 AND @P2", conn);
                    cmd.Parameters.AddRange(new SqliteParameter[] { new SqliteParameter("@P1", MinId), new SqliteParameter("@P2", MaxId) });

                    using (var reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            while (reader.Read())
                            {
                                var dm = new SlotCurrentRecord();

                                int col = 0;
                                dm.Id = reader.GetInt64(col++);
                                dm.IsDeleted = reader.GetBoolean(col++);
                                dm.Parent = reader.GetInt64(col++);
                                dm.Slot = reader.GetInt64(col++);
                                dm.A1 = reader.GetDouble(col++);
                                dm.A2 = reader.GetDouble(col++);
                           //     dm.A3 = reader.GetDouble(col++);
                                dm.B1 = reader.GetDouble(col++);
                                dm.B2 = reader.GetDouble(col++);
                             //   dm.B3 = reader.GetDouble(col++);
                                list.Add(dm);
                            }
                        }
                    }
                }

                // 产线记录和槽记录匹配
                foreach (var slot in list)
                {
                    if (dict.ContainsKey(slot.Parent))
                    {
                        if (0 < slot.Slot && slot.Slot <= dict[slot.Parent].SlotCurrent.Length)
                            dict[slot.Parent].SlotCurrent[slot.Slot - 1] = slot;
                    }
                }
            }

            return dict.Values.ToList();
        }

        /// <summary>
        /// 查询N天数据
        /// </summary>
        /// <param name="start">起始日期</param>
        /// <param name="days">天数</param>
        /// <returns></returns>
        public static List<CurrentRecordView> Select(DateTime aday, int days)
        {
            var t0 = aday.Date;
            var t1 = aday.Date.AddDays(days);
            return Select(t0, t1);
        }

        /// <summary>
        /// 查询某天的数据
        /// </summary>
        /// <param name="day"></param>
        /// <returns></returns>
        public static List<CurrentRecordView> Select(DateTime day)
        {
            return Select(day, 1);
        }
    }
}
